import pandas as pd
import numpy as np

data = pd.read_excel("数据文件.xlsx", sheet_name=0, header=0, index_col=0)
m, n = data.shape  # 获取行数m和列数n


# 熵权法计算
def normalizationMatrix(data1):  # 矩阵标准化(min-max标准化)
    for i in data1.columns:
        for j in range(n + 1):
            if i == str(f'X{j}负'):  # 负向指标
                data1[i] = (np.max(data1[i]) - data1[i]) / (np.max(data1[i]) - np.min(data1[i]))
            else:  # 正向指标
                data1[i] = (data1[i] - np.min(data1[i])) / (np.max(data1[i]) - np.min(data1[i]))
    return data1


Y_ij = normalizationMatrix(data)  # 标准化矩阵
None_ij = [[None] * n for i in range(m)]  # 新建空矩阵


def calcEntropy(data3):  # 计算熵值
    data3 = np.array(data3)
    E = np.array(None_ij)
    for i in range(m):
        for j in range(n):
            if data3[i][j] == 0:
                e_ij = 0.0
            else:
                P_ij = data3[i][j] / data3.sum(axis=0)[j]  # 计算比重
                e_ij = (-1 / np.log(m)) * P_ij * np.log(P_ij)
            E[i][j] = e_ij
    E_j = E.sum(axis=0)
    return E_j


entropy_j = calcEntropy(Y_ij)  # 熵值
E_j = pd.Series(entropy_j, index=data.columns, name='熵值')
G_j = 1 - entropy_j  # 计算差异系数
G_j = pd.Series(G_j, index=data.columns, name='信息效用值')
W_j = G_j / sum(G_j)  # 计算权重
WW = pd.Series(W_j, index=data.columns, name='指标权重')
# print(WW)
Y_ij.to_excel("(2)-标准化后的评价矩阵-Y.xlsx", sheet_name='Y')
E_j.to_excel("(3)-1-熵值-Ej.xlsx", sheet_name='Ej')
G_j.to_excel("(3)-2-信息效用值-Dj.xlsx", sheet_name='Dj')
WW.to_excel("(4)-指标权重-Wj.xlsx", sheet_name='Wj')

# TOPSIS计算
Y_ij = np.array(Y_ij)  # Y_ij为标准化矩阵
Z_ij = np.array(None_ij)  # 空矩阵
for i in range(m):
    for j in range(n):
        Z_ij[i][j] = Y_ij[i][j] * W_j[j]  # 计算加权标准化矩阵Z_ij
data_Z_ij = pd.DataFrame(Z_ij)
writer = pd.ExcelWriter('(5)-加权规范化决策矩阵-Vij.xlsx')
data_Z_ij.to_excel(writer, 'Vij')
writer.close()
# Z_ij_ori = pd.Series(Z_ij, index=data.columns, name='加权标准化矩阵')
# Z_ij_ori.to_excel("加权标准化矩阵.xlsx", sheet_name='加权标准化矩阵')
I_j_max = Z_ij.max(axis=0)  # 最优解
I_j_min = Z_ij.min(axis=0)  # 最劣解

# data_I_j_max = pd.DataFrame(I_j_max)
# writer = pd.ExcelWriter('(6)-1-正理想解-V+.xlsx')
# data_I_j_max.to_excel(writer, 'V+')
data_I_j_max = pd.Series(I_j_max, name='正理想解')
data_I_j_max.to_excel("(6)-1-正理想解-V+.xlsx", sheet_name='D_i_max')

# data_I_j_min = pd.DataFrame(I_j_min)
# writer = pd.ExcelWriter('(6)-2-负理想解-V-.xlsx')
# data_I_j_min.to_excel(writer, 'V-')

data_I_j_min = pd.Series(I_j_min, name='负理想解')
data_I_j_min.to_excel("(6)-2-负理想解-V-.xlsx", sheet_name='D_i_min')


Dmax_ij = np.array(None_ij)
Dmin_ij = np.array(None_ij)

for i in range(m):
    for j in range(n):
        Dmax_ij[i][j] = (I_j_max[j] - Z_ij[i][j]) ** 2
        Dmin_ij[i][j] = (I_j_min[j] - Z_ij[i][j]) ** 2

D_i_max = Dmax_ij.sum(axis=1) ** 0.5  # 最优解欧氏距离
D_i_min = Dmin_ij.sum(axis=1) ** 0.5  # 最劣解欧氏距离
C_i = D_i_min / (D_i_max + D_i_min)  # 综合评价值

D_i_max = pd.Series(D_i_max, index=data.index, name='最优解欧氏距离')
D_i_max.to_excel("(7)-1-正理想解的欧式距离-D_i_max.xlsx", sheet_name='D_i_max')
D_i_min = pd.Series(D_i_min, index=data.index, name='最劣解欧氏距离')
D_i_min.to_excel("(7)-2-负理想解的欧式距离-D_i_min.xlsx", sheet_name='D_i_min')
C_i = pd.Series(C_i, index=data.index, name='贴近度')
C_i.to_excel("(8)-贴近度-Ti.xlsx", sheet_name='Ti')